#include "BCDPUStatus.h"

//************************************
// Method:    	BCDPU_PACK_Make				打包程序
// Programmer:  lww
// Time:		2019/2/16
// Returns:   	int							打包字节数
// Parameter: 	void * Data					数据区头指针
// Parameter: 	short Head					报头
// Parameter: 	short Tail					报尾
//************************************
int BCDPU_PACK_Make(void* Data, short Head, short Tail)
{
#define MEMWRITE1(name)	MEMWRITE(name, Data);
	int _iLen = 0;
	short tmp_short;
	int i, j;
	Card_Base_t* _base;
	
	//< 报头
	MEMWRITE1(Head);	
	//< 站号
	tmp_short = Station_ID;
	MEMWRITE1(tmp_short);
	//< IP地址最后一位
	tmp_short = IPTail_Num;
	MEMWRITE1(tmp_short);
	
	//< 从该处往后不加报尾还有多少个字节（不包括该处），上位通过此处先对报尾进行校验
	tmp_short = (short)(8 + 5 * Card_TotalNum);
	MEMWRITE1(tmp_short);

	//< 系统主从站状态
	if (SYS_Role == Master_Alone_Role || SYS_Role == Master_Twins_Role)
		tmp_short = 1;
	else if (SYS_Role == Slave_Role)
		tmp_short = 2;
	else
		tmp_short = 3;
	MEMWRITE1(tmp_short);
	
	//< 系统状态
	tmp_short = SYS_Status;
	MEMWRITE1(tmp_short);
	//printf("duanyacan_当前系统的状态时%d\r\n", tmp_short);

	//< 系统文件下装状态，1为下装完成，0为未下装，此处通过系统状态判断得到
	if (SYS_Status == Default_Status || SYS_Status == File_Wait_Status)
		tmp_short = 0;
	else
		tmp_short = 1;
	MEMWRITE1(tmp_short);

	//< 该站IO卡数量
	tmp_short = (short)Card_TotalNum;
	MEMWRITE1(tmp_short);
	//< 循环写入卡件信息
	for (i = 0; i < TYP_MAX_CARD; i++)
	{
		if (i == TYP_SAMAIO) { continue; }
		for (j = 0; j < Card_List[i].iCount; j++)
		{
			_base = (Card_Base_t*)SearchAt(((List_Base_t*)Card_List[i].ppData[0]), j);
			//< IO卡号
			MEMWRITE1(_base->List_Base.ID);
			//< 状态
			MEMWRITE1(_base->Status);
		}
	}
	   
	//< 报尾
	MEMWRITE1(Tail);
	return _iLen;
}


//************************************
// Method:    	tBCDPUStatus			广播DPU状态
// Programmer:  lww
// Time:		2018/12/22
// Returns:   	void *
// Parameter: 	void * arg
//************************************
void *tBCDPUStatus(void* arg)
{
#define PACK_MAXNUM	8192 //lijun20220723更改：因数据点大幅增加，上位和下位此处由2048提至8192
	int sock;
	struct sockaddr_in NetA;
	struct sockaddr_in NetB;
	timer_t BCDPU_Timer;
	struct timespec time;
	short Head = 7688;				//< 报头
	short Tail = 1434;				//< 报尾
	char Data2Send[PACK_MAXNUM];	//< 存放数据包的数组
	int _iLen = 0;

	printf("the Kernel_%s is %d\r\n", "tBCDPUStatus_ID", syscall(SYS_gettid));			//< duan20200610

	//< 初始化UDP设置
	if (false == UDP_Init(&sock, BCDPU_PORT, 0, 0, UDP_SEND_STATUS, nullptr)) { return 0; }

	//< 设置发送到的IP地址及端口
	Addr_Set(&NetA, BCDPU_PORT, inet_addr(NETA_IP_BC));
	Addr_Set(&NetB, BCDPU_PORT, inet_addr(NETB_IP_BC));
	
	//< 设置广播周期
	MS2TimeSpec(&time, BCDPU_PERIOD);

	//< 开启定时中断
	Timer_Create(&BCDPU_Timer, BcDPUSIG, &time);
	while (1)
	{		
		//< 等待信号量释放进行广播操作
		/*MUTEX_LOCK(BcDPU_Mutex, "BcDPU_Mutex lock failed");*/
		SEM_WAIT(BcDPUSemId, "BcDPUSemId wait failed");

		//< 数据打包
		_iLen = BCDPU_PACK_Make(Data2Send, Head, Tail);

		//< 发送数据
		if (-1 == UDP_Send(&sock, &NetA, (char*)Data2Send, _iLen))
		{
			SYS_NetA_Status = Net_Trouble;
		}
		else
		{
			SYS_NetA_Status = Net_Normal;
		}

		if (-1 == UDP_Send(&sock, &NetB, (char*)Data2Send, _iLen))
		{
			SYS_NetB_Status = Net_Trouble;
		}
		else
		{
			SYS_NetB_Status = Net_Normal;
		}
	}
	close(sock);//< 断开连接
#undef PACK_MAXNUM
}
